package com.wen.common.util;

import org.apache.commons.lang.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

/**
 * 日期工具类
 * 
 * @author Administrator
 * @version [版本号, 2015年1月12日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public final class DateUtils {
    /**
     * 默认时间格式
     */
    public static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    
    /**
     * 年月日格式
     */
    public static final String DATE_FORMAT = "yyyy-MM-dd";
    
    /**
     * 一天的小时数
     */
    private static final int HOUR_OF_DAY = 24;
    
    /**
     * 一小时的分钟数
     */
    private static final int MINUTE_OF_HOUR = 60;
    
    /**
     * 一分钟的秒数
     */
    private static final int SECOND_OF_MINUTE = 60;
    
    /**
     * 毫秒数
     */
    private static final int MILLIS = 1000;
    
    private DateUtils() {
        
    }
    
    /**
     * 对给定的日期以"yyyy-MM-dd"格式化
     * 
     * @param date 指定的日期对象
     * @param format 格式字符串
     * @return
     */
    public static String format(Date date, String format) {
        if (StringUtils.isEmpty(format)) {
            format = DATETIME_FORMAT;
        }
        if (null != date) {
            DateFormat dateFormat = new SimpleDateFormat(format, Locale.CHINA);
            
            return dateFormat.format(date);
        }
        
        return null;
    }
    
    /**
     * 字符串转日期
     * 
     * @param dateStr
     * @return
     */
    public static Date stringToDate(String dateStr) {
        return stringToDate(dateStr, null);
    }
    
    /**
     * 字符串转日期
     * 
     * @param dateStr
     * @param format
     * @return
     */
    public static Date stringToDate(String dateStr, String format) {
        if (format == null) {
            format = DATETIME_FORMAT;
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        Date date = null;
        try {
            date = simpleDateFormat.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
    
    /**
     * 根据指定的日期，计算距离到当前日期的天数(不包含当天)，指定是日期必须是2014-3-1格式
     * 
     * @param strStartDate 指定的日期字符串
     * @return 表示距离的天数
     */
    public static long startDateToNowDays(String strStartDate) {
        long quot = 0;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date now = new Date();
            DateFormat dateFormat = DateFormat.getDateInstance();
            String strNowDate = dateFormat.format(now);
            
            Date nowDate = simpleDateFormat.parse(strNowDate);
            Date startDate = simpleDateFormat.parse(strStartDate);
            quot = nowDate.getTime() - startDate.getTime();
            quot = quot / 1000 / 60 / 60 / 24;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        
        return quot;
    }
    
    /**
     * 检查两个日期对象是否是同一天，忽略时间
     * 
     * @param date1 第一个日期对象，不能为null
     * @param date2 第二个日期对象，不能为null
     * @return 如果是同一天，则返回true
     */
    public static boolean isSameDay(Date date1, Date date2) {
        // 非空检查
        if (date1 == null || date2 == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);
        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        
        return isSameDay(cal1, cal2);
    }
    
    /**
     * 检查两个日历对象是否是同一天，忽略时间
     * 
     * @param calendar1 第一个日历对象，不能为null
     * @param calendar2 第二个日历对象，不能为null
     * @return 如果是同一天，则返回true
     */
    public static boolean isSameDay(Calendar calendar1, Calendar calendar2) {
        // 非空检查
        if (calendar1 == null || calendar2 == null) {
            throw new IllegalArgumentException("The date must not be null");
        }
        
        return calendar1.get(Calendar.ERA) == calendar2.get(Calendar.ERA) && calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR) && calendar1.get(Calendar.DAY_OF_YEAR) == calendar2.get(Calendar.DAY_OF_YEAR);
    }
    
    /**
     * 获取当前日期，所在月份第一天日期
     *
     * 日期以"yyyy-MM-dd"格式化
     * 
     * @return 表示月份第一天日期字符串：2017-11-01 00:00:01
     */
    public static String getMonthFirstDay() {
        return getMonthFirstDay(null);
    }
    
    /**
     * 根据指定日期，获取所在月份第一天日期字符串
     *
     * 日期以"yyyy-MM-dd"格式化
     * 
     * @return 表示月份第一天日期字符串：2017-11-01 00:00:01
     */
    public static String getMonthFirstDay(Date date) {
        if (date == null) {
            date = new Date();
        }
        
        Calendar calendar = Calendar.getInstance(Locale.CHINA);
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 0);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), 1, 0, 0, 1);
        String monthFirstDay = DateUtils.format(calendar.getTime(), null);
        
        return monthFirstDay;
    }
    
    /**
     * 根据指定的日期，获取月的第一天
     * 
     * @param date 月份时间,为空时 取当前时间
     * @param month 要减去的月份数, 1表示往前一个月, -1表示往后一个月,0表示当前月
     * @return 时间格式:2015-06-01 00:00:01
     */
    public static Date getMonthFirstDay(Date date, int month) {
        if (date == null) {
            date = new Date();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) - month, 1, 0, 0, 1);
        return calendar.getTime();
    }
    
    /**
     * 获取当前日期所在月份最后一天日期字符串
     *
     * 日期以"yyyy-MM-dd"格式化
     * 
     * @return 表示月份最后一天日期字符串
     */
    public static String getMonthLastDay() {
        return getLastDayOfMonth(null);
    }
    
    /**
     * 获取指定日期月的最后一天
     * 
     * @param date 指定的日期
     * @return 时间格式:2015-11-30 11:59:59
     */
    public static Date getMonthLastDay(Date date) {
        if (date == null) {
            date = new Date();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 1);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), 0, 23, 59, 59);
        
        return calendar.getTime();
    }
    
    /**
     * 根据指定日期，获取指定日期的所在月份的最后一天
     * 
     * @param date 表示月的最后一天日期,如:2017-12-31 23:59:59
     * @return
     */
    public static String getLastDayOfMonth(Date date) {
        if (date == null) {
            date = new Date();
        }
        
        Calendar calendar = Calendar.getInstance(Locale.CHINA);
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 1);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), 0, 23, 59, 59);
        
        String monthLastDay = DateUtils.format(calendar.getTime(), null);
        
        return monthLastDay;
    }
    
    /**
     * 根据当前日期，获取当前日期所在星期一的日期字符串
     *
     * 星期一的日期以"yyyy-MM-dd"格式化
     * 
     * @return 表示星期一的日期字符串，如：2014-09-22
     */
    public static String getNowDateMonday() {
        Calendar calendar = Calendar.getInstance(Locale.CHINA);
        
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        
        return format(calendar.getTime(), DATE_FORMAT);
    }
    
    /**
     * 当前时间上周一日期
     * 
     * @return 表示上周一日期对象
     */
    public static Date getLastWeekMonday() {
        Calendar calendar = Calendar.getInstance(Locale.CHINA);
        calendar.add(Calendar.WEEK_OF_MONTH, -1);
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        
        return calendar.getTime();
    }
    
    /**
     * 当前时间上周日日期
     * 
     * @return 表示上周日期对象
     */
    public static Date getLastWeekSunday() {
        Calendar calendar = Calendar.getInstance(Locale.CHINA);
        calendar.add(Calendar.DAY_OF_WEEK, 1);
        calendar.setFirstDayOfWeek(Calendar.SUNDAY);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        
        return calendar.getTime();
    }
    
    /**
     * 根据当前日期，获取昨天的日期
     * 
     * @return
     */
    public static Date getYesterday() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(calendar.DATE, -1);// 把日期往前减少一天，若想把日期向后推一天则将负数改为正数
        Date date = calendar.getTime();
        
        return date;
    }
    
    /**
     * 当天的开始时间字符串
     * 
     * @return
     */
    public static String yesterdayFirst() {
        Calendar calendar = Calendar.getInstance(Locale.CHINA);
        calendar.setTime(new Date());
        calendar.add(calendar.DATE, -1);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE), 0, 0, 1);
        String monthFirstDay = DateUtils.format(calendar.getTime(), null);
        
        return monthFirstDay;
    }
    
    /**
     * 当天开始时间的结束时间
     * 
     * @return
     */
    public static String yesterdayLast() {
        Calendar calendar = Calendar.getInstance(Locale.CHINA);
        calendar.setTime(new Date());
        calendar.add(calendar.DATE, -1);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE), 23, 59, 59);
        String monthFirstDay = DateUtils.format(calendar.getTime(), null);
        
        return monthFirstDay;
    }
    
    /**
     * 将指定的日期后推一天
     * 
     * @param curDate 指定的日期
     * @return 表示后推一天后的日期
     */
    public static Date getNextDate(Date curDate) {
        /**
         * 非空检查
         */
        if (null == curDate) {
            return null;
        }
        curDate.setTime(curDate.getTime() + HOUR_OF_DAY * MINUTE_OF_HOUR * SECOND_OF_MINUTE * MILLIS);
        
        return curDate;
    }
    
    /**
     * 获取两个日期相差几个月
     * 
     * @author 石冬冬-Heil Hilter(dd.shi02@zuche.com)
     * @date 2016-11-30 下午7:57:32
     * @param start
     * @param end
     * @return
     */
    public static int getMonth(Date start, Date end) {
        if (start.after(end)) {
            Date t = start;
            start = end;
            end = t;
        }
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(start);
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(end);
        Calendar temp = Calendar.getInstance();
        temp.setTime(end);
        temp.add(Calendar.DATE, 1);
        
        int year = endCalendar.get(Calendar.YEAR) - startCalendar.get(Calendar.YEAR);
        int month = endCalendar.get(Calendar.MONTH) - startCalendar.get(Calendar.MONTH);
        
        if ((startCalendar.get(Calendar.DATE) == 1) && (temp.get(Calendar.DATE) == 1)) {
            return year * 12 + month + 1;
        } else if ((startCalendar.get(Calendar.DATE) != 1) && (temp.get(Calendar.DATE) == 1)) {
            return year * 12 + month;
        } else if ((startCalendar.get(Calendar.DATE) == 1) && (temp.get(Calendar.DATE) != 1)) {
            return year * 12 + month;
        } else {
            return (year * 12 + month - 1) < 0 ? 0 : (year * 12 + month);
        }
    }
    
    /**
     * 获取年
     * 
     */
    public static Integer getYear() {
        return getYear(null);
    }
    
    /**
     * 获取年
     *
     * @param date 可以为空
     */
    public static Integer getYear(Date date) {
        if (date == null) {
            date = new Date();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR);
    }
    
    /**
     * 获取月
     * 
     */
    public static Integer getMonth() {
        return getMonth(null);
    }
    
    /**
     * 获取月
     *
     * @param date 可以为空
     */
    public static Integer getMonth(Date date) {
        if (date == null) {
            date = new Date();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) + 1;
    }
    
    public static void main(String[] args) {
        String bengDate = "2018-12-01";
        String endDate = "2018-12-30";
        int d = getMonth(stringToDate(bengDate, "yyyy-MM-dd"), stringToDate(endDate, "yyyy-MM-dd"));
        
        System.out.println(d);
    }
    
}